# layertopo.mod    
# by Yu Liu, 03/2001.   Based on arcflow.mod
# Arc-flow model for topology and working capacity allocation 
# considering all single NODE failures

# Lower layer nodes and network
set VERTS;
set EDGES within {i1 in VERTS, VERTS diff {i1}};

param oBL {VERTS,EDGES} binary default 0;
param dBL {VERTS,EDGES} binary default 0;
param BL {VERTS,EDGES} integer default 0 >= -1 <= 1;

#  First define higher layer network
set NODES within VERTS;
set LINKS within {i1 in NODES, NODES diff {i1}};
set FLOWS := {i1 in NODES, NODES diff {i1}};
param M {FLOWS} integer default 1 >=0; 

param oB {NODES,LINKS} binary default 0;
param dB {NODES,LINKS} binary default 0;
param B {NODES,LINKS} integer default 0 >= -1 <= 1;
param oD {FLOWS,NODES} binary default 0;
param dD {FLOWS,NODES} binary default 0;
param D {FLOWS,NODES} integer default 0 >= -1 <= 1;

var H {LINKS, EDGES} binary default 0;
var T {LINKS} binary default 1;
var T1 {(i1,i2) in LINKS, NODES diff {i1,i2}} binary default 1;
#var A {FLOWS, LINKS} binary;
#var w {LINKS} integer default 0;

set FAILS := EDGES;
param F {FAILS, EDGES} binary default 0;

param MaxVert integer;
param MaxEdge integer;
param MaxNode integer ;
param MaxLink integer ;
set POWNODES := 1 .. 2**MaxNode - 2; #get rid of 0 and 2^N -1, null cuts
set CUTS {k in POWNODES} := {i in NODES: (k div 2**(i-1)) mod 2 = 1};

minimize topo_cost: 
  sum {(i1,i2) in LINKS, (j1,j2) in EDGES} H[i1,i2,j1,j2];

minimize topo_aggr: 
#  sum {(i1,i2) in LINKS, (j1,j2) in EDGES} H[i1,i2,j1,j2]+
  sum {(i1,i2) in LINKS} T[i1,i2];

s.t. mass_baH {(i1,i2) in LINKS, n1 in NODES}:
  sum {(j1,j2) in EDGES} BL[n1,j1,j2] * H[i1,i2,j1,j2]
      = B[n1,i1,i2];
s.t. mass_baH2 {(i1,i2) in LINKS, n1 in VERTS diff NODES}:
  sum {(j1,j2) in EDGES} BL[n1,j1,j2] * H[i1,i2,j1,j2]
      = 0;

# KH < Ke
s.t. survH {(j1,j2) in EDGES, k in POWNODES}:
  sum{v1 in CUTS[k], v2 in NODES diff CUTS[k]:(v1,v2) in LINKS}
    (1- H[v1,v2,j1,j2]) >= 1; 

s.t. mergeH {(n1,n2) in LINKS, n3 in NODES diff {n1,n2}, (j1,j2) in EDGES}:
  H[n1,n3,j1,j2] + H[n3,n2,j1,j2] - H[n1,n2,j1,j2] <= T1[n1,n2,n3]*100;

s.t. mergeH2 {(n1,n2) in LINKS, n3 in NODES diff {n1,n2}, (j1,j2) in EDGES}:
  -H[n1,n3,j1,j2] -H[n3,n2,j1,j2] + H[n1,n2,j1,j2] <= T1[n1,n2,n3]*100;

s.t. getT {(n1,n2) in LINKS}:
  sum{n3 in NODES diff {n1,n2}} T1[n1,n2,n3] <= T[n1,n2] + MaxNode -3;  
  #one zero in T1 will drag T down to 0.

problem designH: topo_cost, mass_baH, mass_baH2, survH, H;
problem aggrH: topo_aggr, mass_baH, mass_baH2, survH, 
  mergeH, mergeH2, getT, 
  H, T1, T;

#var B {FLOWS, LINKS} binary default 0;
#var C {LINKS, FAILS} integer default 0;
#var s {LINKS} integer default 0;

#minimize w_cap:  sum {(i1,i2) in LINKS} w[i1,i2];
#s.t. mass_ba {(r1,r2) in FLOWS, n1 in NODES}:
#  sum {(i1,i2) in LINKS} A[r1,r2,i1,i2]*R[n1,i1,i2] 
#      = D[r1,r2,n1];
#s.t. cap_aggr {(i1,i2) in LINKS}:
#  w[i1,i2] = sum{(r1,r2) in FLOWS} A[r1,r2,i1,i2];
#problem find_work:  work_cost,  mass_ba, cap_aggr, A, w;

param MaxFlow integer default 10;
param MaxHop integer default 6;

param t1 integer;
param t2 integer;
param ss integer;